<?php

/*
 * Optimize Count Query
 *
 */

/**
 * vente-unique Doctrine pager class.
 *
 * @package    
 * @subpackage pager
 * @author     
 * @version    SVN: $Id:$
 */
class vuDoctrinePager extends sfDoctrinePager
{

  protected $relatedResults   = null;
  protected $queryWhitRelated = null;
  protected $cache_key        = null;
  protected $pks              = null;
  
  public function init(){


    // recupere les ids
    $this->relatedResults = array();
    
    if($this->pks !== null){
      $this->resetIterator();
      
      $count = count($this->pks);
      $this->setNbResults($count);


      $offset = ($this->getPage() - 1) * $this->getMaxPerPage();
      $this->setLastPage(ceil($this->getNbResults() / $this->getMaxPerPage()));


      $mypks = array_slice($this->pks, $offset, $this->getMaxPerPage());

      foreach($mypks as $pk){
        $this->relatedResults[$pk] = null;
      }
    }else{
    
      // recupere le nombre d'enregistrement
      parent::init();
    
      $q = $this->getQuery();
      $rootAlias = $q->getRootAlias();
      $q->select($rootAlias . '.id');
      
      if($this->cache_key){
        $key = __CLASS__ . '__ids__'.$this->cache_key .'__'.md5($q->getSqlQuery());
        $q->useResultCache(
              sfConfig::get('app_memcache_activate')? true : null,
              null, 
              $key
              );
      }
      
      $rs = $q->execute();

      foreach($rs as $obj){
        $this->relatedResults[$obj->id] = null;
      }
    }

    // todo free memory of Query
  }
  
  
  public function getResults($hydrationMode = null)
  {
  	if($this->relatedResults === null){
      throw new sfException('You must init your pager');
    }
    
    if(count($this->relatedResults) == 0){
      return array();
    }
  
    if( current($this->relatedResults) != null ){
      return $this->relatedResults;
    }

    $queryRelationObject = $this->getQueryWithRelated();
    if($queryRelationObject == null){
      throw new sfException('You must setQueryWithRelated');
    }
    
    $rootAlias = $queryRelationObject->getRootAlias();

    $ids = array_keys($this->relatedResults);
    if(count($ids) == 1 && array_key_exists(0,$ids)){
      $queryRelationObject
        ->where($rootAlias.'.id = ?', $ids[0])
      ;
      
      //$qRelated = $this->getQueryWithRelated();
      if($this->cache_key){
        $key = __CLASS__ . '__relatedOne__'.$this->cache_key.'__'.md5($queryRelationObject->getSqlQuery().$ids[0]);
        $queryRelationObject->useResultCache(
              sfConfig::get('app_memcache_activate')? true : null,
              null, 
              $key
              );
      }
      
      $rsOne = $queryRelationObject->execute(array(), $hydrationMode);
      
      $rsOne = $rsOne->getData();
      $obj = null;
      if(is_array($rsOne) && array_key_exists(0,$rsOne)){
        $obj = $rsOne[0];
      }else{
        $obj = $rsOne;
      }
      if($obj && array_key_exists($obj->getId(),$this->relatedResults)){
        $this->relatedResults[$obj->getId()] = $obj;
      }
    }else{

    
      $queryRelationObject
        ->whereIn($rootAlias.'.id', $ids)
      ;

      if($this->cache_key){
        $key = __CLASS__ . '__related__'.$this->cache_key.'__'.md5($queryRelationObject->getSqlQuery().serialize($ids));
        $queryRelationObject->useResultCache(
              sfConfig::get('app_memcache_activate')? true : null,
              null, 
              $key
              );
      }
      $rsNoOrder = $queryRelationObject->execute(array(), $hydrationMode);
      

      

      // order
      foreach($rsNoOrder as $obj){
        if(array_key_exists($obj->getId(),$this->relatedResults)){
          $this->relatedResults[$obj->getId()] = $obj;
        }
      }
    }

    return $this->relatedResults;
  }

  public function setQueryWithRelated($query)
  {
    $this->queryWhitRelated = $query;
  }

  public function getQueryWithRelated()
  {
    return $this->queryWhitRelated;
  }
 
  public function getExecuted(){
    return $this->getResults();
  }
  
  public function setQueryCacheKey($key){
    $this->cache_key = $key;
  }
  
  public function setPksByLucene($pks){
    $this->pks = $pks;
  }
  
}